package com.baomidou.springmvc.interceptor;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.baomidou.springmvc.controller.UserController;
/**
 * 
 * @author hewei
 * @ClassName: RequestUrlFilter
 * @Copyright beauty_tech
 * @date 2018年2月6日 下午12:14:05
 * @description 1、防止sql注入攻击(主要)、2防止xss攻击
 */

@Aspect
@Component
public class RequestUrlFilter {
	private static Logger log = Logger.getLogger(RequestUrlFilter.class);
	///@Value("${OLD_FILTER_KEYS_STRING}")
	String OLD_FILTER_KEYS_STRING = "PARAMETER^SCRIPT^ALERT^PROMPT^APPEND^DOCUMENT^CONFIRM^EVAL^JAVASCRIPT^<SCRIPT>";
	//@Value("${FILTER_KEYS_STRING}")
	String FILTER_KEYS_STRING = "^ and^and ^ and ^alert(^script^iframe^ exec^ exec ^exec ^ or^or ^ or ^sleep^*^ if^if ^ if ^'^execute^ insert^insert ^ select^select ^ delete^delete ^ update^update ^ count^count ^ drop^drop ^*^%^ chr^chr ^||chr^chr(^ mid^mid ^ master^master ^ truncate^truncate ^ char^char ^ declare^declare ^sitename^net user^xp_cmdshell^ like^like ^ create^create ^ table^table ^ from^from ^ grant^grant ^ use^use ^group_concat^column_name^information_schema.columns^table_schema^ union^union ^ where^where ^ order^ by^order ^by ^--^%^content-^eval(^document^textarea^prompt^onclick^ confirm^confirm (^<^>^'^javascript^jscript^vbscript^%3C^%3E";
	
	/**
	 * 
	 * @description 定义所有controller中的public方法并且有RequestMapping和RequestBody的标签的切点
	 * @author hewei
	 * @title: requestUrlPointcut
	 * @date 2018年2月6日 下午12:13:56 void
	 */
	@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
	public void requestUrlPointcut() {
	}
	
	@Before(value = "requestUrlPointcut()")
	private boolean hasFilterAttackScriptByGET(JoinPoint joinPoint) throws  IOException {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		// String postData = this.getBody(request);
		// // 有sql关键字，跳转到error.html
		// if (StringUtils.isNotBlank(postData) && sqlValidate(postData)) {
		// logger.debug("可能有脚本攻击(指定关键字),传入值[" + postData + "]，拒绝服务!");
		// throw new
		// XwtechException(WebClientConstants.MsgCode.TASK_QUERY_EXCEPTION,
		// "您发送请求中的参数中含有非法字符：" + postData);
		// }
		// 获得所有请求参数名
		Enumeration<String> params = request.getParameterNames();
		String sql = "";
		while (params.hasMoreElements()) {
			// 得到参数名
			String name = params.nextElement().toString();
			// 得到参数对应值
			String[] value = request.getParameterValues(name);
			for (int i = 0; i < value.length; i++) {
				sql = sql + "," + value[i];
			}
		}
		// 有sql关键字，跳转到error.html
		if (StringUtils.isNotBlank(sql) && sqlValidate(sql)) {
			log.error("=================可能有脚本攻击(指定关键字),传入值[" + sql + "],拒绝服务!");
			throw new RuntimeException("您发送请求中的参数中含有非法字符：" + sql);
		}
		return true;
	}
	
	// 效验
	protected boolean sqlValidate(String str) {
		str = str.toLowerCase();// 统一转为小写
		// String badStr =
		// "'|select|update|and|or|delete|insert|truncate|char|into"
		// + "|substr|declare|exec|master|drop|execute|"
		// + "union|;|--|+|,|like|//|/|%|#|*|$|@|\"|http|cr|lf|<|>|(|)";//
		// 过滤掉的sql关键字，可以手动添加
		// String[] badStrs = badStr.split("\\|");
		String FILTER_KEYS_STRING = " ^ and^and ^ and ^alert(^script^iframe^ exec^ exec ^exec ^ or^or ^ or ^sleep^*^ if^if ^ if ^'^execute^ insert^insert ^ select^select ^ delete^delete ^ update^update ^ count^count ^ drop^drop ^*^%^ chr^chr ^||chr^chr(^ mid^mid ^ master^master ^ truncate^truncate ^ char^char ^ declare^declare ^sitename^net user^xp_cmdshell^ like^like ^ create^create ^ table^table ^ from^from ^ grant^grant ^ use^use ^group_concat^column_name^information_schema.columns^table_schema^ union^union ^ where^where ^ order^ by^order ^by ^--^%^content-^eval(^document^textarea^prompt^onclick^ confirm^confirm (^<^>^'^javascript^jscript^vbscript^%3C^%3E";
		String[] badStrs = FILTER_KEYS_STRING.split("\\^");
		// String[] badStrs = FILTER_KEYS_STRING.split("\\^");
		for (int i = 0; i < badStrs.length; i++) {
			if (StringUtils.isBlank(badStrs[i])) {
				continue;
			}
			if (str.indexOf(badStrs[i]) >= 0) {
				System.out.println(badStrs[i]);
				return true;
			}
		}
		return false;
	}
	
	/**
	 * getPost的参数数据
	 * 
	 * @param request
	 * @return
	 * @throws IOException
	 */
	/*@SuppressWarnings("unused")
	private String getBody(HttpServletRequest request) throws IOException {
		String body = null;
		StringBuilder stringBuilder = new StringBuilder();
		BufferedReader bufferedReader = null;
		try {
			InputStream inputStream = request.getInputStream();
			if (inputStream != null) {
				bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
				char[] charBuffer = new char[128];
				int bytesRead = -1;
				while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
					stringBuilder.append(charBuffer, 0, bytesRead);
				}
			}
			else {
				stringBuilder.append("");
			}
		}
		catch (IOException ex) {
			throw ex;
		}
		finally {
			if (null != bufferedReader) {
				bufferedReader.close();
			}
		}
		body = stringBuilder.toString();
		return body;
	}*/
	
	public static void main(String[] args) {
		System.out.println("===================");
	}
}
